﻿using Ivi.Visa.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test_Libscvs.Instrument
{
    public class Dso_Set
    {
        public FormattedIO488 DSO_IO = null;
        public bool _enaSimulate = false; //用来表示仪表是否运行于offline模式下
        public string mode;
        public string dsotype;
        public string Load_initial(string addr, bool simu, bool reset)
        {
            ResourceManager rm = new ResourceManager();
            DSO_IO = new FormattedIO488();
            string idn = null;
            try
            {
                DSO_IO = new Ivi.Visa.Interop.FormattedIO488();
                if (!simu)
                {
                    DSO_IO.IO = (IMessage)rm.Open(addr, AccessMode.NO_LOCK, 10000, "");
                    DSO_IO.IO.Timeout = 5000;
                    DSO_IO.WriteString("*IDN?", true); //Get the IDN string
                    idn = DSO_IO.ReadString();
                    string info = null;
                    if (reset)
                        info = Reset();   //Reset the device
                    //DSO_IO.WriteString(":SYSTem:HEADer OFF");
                    Thread.Sleep(10);
                    DSO_IO.WriteString(":SYSTem:HEADer OFF");
                    Thread.Sleep(1500);
                    return idn + "+" + info;
                }
                else
                {
                    _enaSimulate = true;
                    return "Simulate";
                }
            }
            catch (Exception ex)
            {
                return "DSO Connect Fail";  //连接失败或者仿真的状态，分别返回不同的字符串
            }
        }
        public string Reset()
        {
            try
            {
                Thread.Sleep(500);
                DSO_IO.WriteString("*RST");
                Thread.Sleep(500);
                DSO_IO.WriteString("*OPC?");
                string resetResult = "Reset fail";
                string name = DSO_IO.ReadString();
                if (name == "1\n")
                {
                    resetResult = "Reset done";
                }
                Thread.Sleep(50);

                return resetResult;
            }
            catch (Exception ex)
            {

                return $"--Scope Reset Error:" + ex.ToString();
            }
        }
        public void close_session()
        {
            if (!_enaSimulate)
            {
                DSO_IO.IO.Close();
            }
        }
        public void Clear()
        {
            try
            {
                DSO_IO.WriteString("*CLS");
            }
            catch (Exception ex)
            {
                return;
            }
        }
        public double Dso_Meas_PP(string channel)
        {
            double output = 0.0;
            if (dsotype == "RIGOL")
            {

                //TestSingle();
                Thread.Sleep(1500);
                DSO_IO.WriteString(":MEASure:STATistic:ITEM? CURRent,VPP,CHANnel" + channel);//量测纹波Peak to Peak  CALCulate:AVERage:PTPeak?
                Thread.Sleep(1500);
                string temp = DSO_IO.ReadString();
                output = Convert.ToDouble(temp) * 1000;
            }
            else
            {
                //TestSingle();
                DSO_IO.WriteString(":CDISplay;*OPC?");
                //Thread.Sleep(100);
                //DSO_IO.WriteString(":SYSTem:HEADer OFF");
                Thread.Sleep(1500);
                DSO_IO.WriteString(":MEASure:VPP? CHANnel" + channel);//量测纹波Peak to Peak  CALCulate:AVERage:PTPeak?
                Thread.Sleep(1500);
                string temp = DSO_IO.ReadString();
                DSO_IO.WriteString(":MEASure:VPP? CHANnel" + channel);//量测纹波Peak to Peak  CALCulate:AVERage:PTPeak?
                Thread.Sleep(50);
                temp = DSO_IO.ReadString();
                output = Convert.ToDouble(temp) * 1000;
            }

            return output;
        }
        public double Dso_Meas_PP()
        {
            double output = 0.0;
            DSO_IO.WriteString(":MEASure:VPP? CHANnel" + 1);//量测纹波Peak to Peak
            Thread.Sleep(10);
            output = Convert.ToDouble(DSO_IO.ReadString());
            return output;
        }
        public string LoadSettingsFile(string filepath)
        {
            try
            {
                string input = $":DISK:LOAD '" + filepath + "'";
                DSO_IO.WriteString(input); //$":DISK:LOAD 'C:\\Users\\Administrator\\Desktop\\1214.set'"
                Thread.Sleep(500);
                return "setting filepath: " + filepath;

            }
            catch (Exception ex)
            {
                return $"--Scope Load Config File Error:" + ex.ToString();
            }
        }
        /// <summary>
        /// TestSingle
        /// </summary>
        public void TestSingle()
        {
            try
            {
                DSO_IO.WriteString(":SINGle;*OPC?");
                //var name = _iO488.ReadList();
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope SINGle Error:" + ex.ToString());
                return;
            }
        }
        public string ReadSingle()
        {
            try
            {
                var name = DSO_IO.ReadString();
                return name;
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope ReadSingle Error:" + ex.ToString());
                return "error";
            }
        }
        /// <summary>
        /// TestSingle
        /// </summary>
        public void MeasureFrequency()
        {
            try
            {
                DSO_IO.WriteString(":MEASure:SOURce CHANnel1");
                DSO_IO.WriteString(":MEASure:FREQuency?");
                var name = DSO_IO.ReadList();
            }
            catch (Exception ex)
            {
                return;
            }
        }

        /// <summary>
        /// 测试周期
        /// </summary>
        /// <param name="channel"></param>
        public double GetPeriod(string channel)
        {
            try
            {
                DSO_IO.WriteString(":MEASure:PERiod? CHANnel" + channel);
                var name = DSO_IO.ReadNumber();
                Thread.Sleep(50);
                return (double)name;
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope GetPeriod Error:" + ex.ToString());
                return -1;
            }
        }
        /// <summary>
        /// 设置占空比
        /// </summary>
        /// <param channel="1"></param>
        /// <param mode="RISing"></param>
        public double GetDutyCycle(string channel)
        {
            try
            {
                DSO_IO.WriteString(":MEASure:DUTYcycle? CHANnel" + channel);
                var name = DSO_IO.ReadNumber();
                Thread.Sleep(50);
                return (double)name;
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope GetPeriod Error:" + ex.ToString());
                return -1;
            }
        }
        public double GetPulseCount(string channel)
        {
            try
            {
                DSO_IO.WriteString(":MEASure:PPULses? CHANnel" + channel);

                var name = DSO_IO.ReadNumber();
                Thread.Sleep(50);
                return (double)name;
                // Set the desired number of waveform points,
                // and capture an acquisition.
                //_iO488.WriteString(":ACQuire:POINts 32000");
                //_iO488.WriteString(":DIGitize");
                //return;
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope GetPeriod Error:" + ex.ToString());
                return -1;
            }
        }
        public void Screenshot(string filename)
        {
            try
            {
                // Download the screen image.
                // -----------------------------------------------------------
                // Get the screen data.
                DSO_IO.WriteString(":CDISplay;*OPC?");
                DSO_IO.WriteString(":DISK:SAVE:IMAGe " + "\'" + filename + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "\'" + ",PNG,SCR,ON,INVert");
                Thread.Sleep(11000);
                //bool response= false;
                //while (response == false)
                //{
                //    response=WaitUntilFinish();
                //}

                //DSO_IO.WriteString(":DISPlay:DATA? PNG");
                //object resultsObj = DSO_IO.ReadIEEEBlock(IEEEBinaryType.BinaryType_I2);
                //byte[] resultsArray = Object2Bytes(resultsObj);
                //int nLength = resultsArray.Length;
                //// Store the screen data to a file.
                //string strPath = @"G:\XY2023\DATALOG\screen_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".png";
                //FileStream fStream = File.Open(strPath, FileMode.Create);
                //fStream.Write(resultsArray, 0, nLength);
                //fStream.Close();
                //Console.WriteLine("Screen image ({0} bytes) written to {1}",
                //nLength, strPath);
                return;
            }
            catch (Exception ex)
            {
                //MessageBox.Show($"--Scope Save Screenshot Error:" + ex.ToString());
                return;
            }
        }
        /* public static byte[] Object2Bytes(object obj)
         {
             byte[] buff;
             using (MemoryStream ms = new MemoryStream())
             {
                 IFormatter iFormatter = new BinaryFormatter();
                 iFormatter.Serialize(ms, obj);
                 buff = ms.GetBuffer();
             }
             return buff;
         }*/
        public bool WaitUntilFinish()
        {
            string dmy = null;
            int opcnum = 0;
            DSO_IO.WriteString("*OPC?", true);
            dmy = DSO_IO.ReadString();
            while (dmy != "1\n")
            {
                dmy = DSO_IO.ReadString();
                Thread.Sleep(10);
                opcnum += 1;
                if (opcnum > 2000)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
